package com.sunwayhorizo.health.business.clinic.emr.template;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.business.base.BaseManager;
import com.sunwayhorizo.health.business.clinic.emr.template.query.ClinicLibraryQueryLocal;
import com.sunwayhorizo.health.business.clinic.emr.template.query.TemplateQueryLocal;
import com.sunwayhorizo.health.business.dto.DictionaryDTO;
import com.sunwayhorizo.health.business.dto.ResultsDTO;
import com.sunwayhorizo.health.business.dto.clinic.emr.template.ClinicLibraryDTO;
import com.sunwayhorizo.health.business.dto.registries.DepartmentDTO;
import com.sunwayhorizo.health.business.registries.organization.DepartmentManagerLocal;
import com.sunwayhorizo.health.common.DataTypeUtil;
import com.sunwayhorizo.health.common.DateUtil;
import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.datatypes.CE;
import com.sunwayhorizo.health.hl7.datatypes.CS;
import com.sunwayhorizo.health.hl7.datatypes.ED;
import com.sunwayhorizo.health.hl7.datatypes.SET_II;
import com.sunwayhorizo.health.hl7.datatypes.ST;
import com.sunwayhorizo.health.hl7.persistent.RimCoreActCdSets;
import com.sunwayhorizo.health.hl7.persistent.RimCoreRoles;
import com.sunwayhorizo.health.hl7.rim.ActParticipation;
import com.sunwayhorizo.health.hl7.rim.ControlAct;
import com.sunwayhorizo.health.hl7.rim.Document;
import com.sunwayhorizo.health.hl7.rim.Organization;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.vocabulary.ActCode;
import com.sunwayhorizo.health.hl7.vocabulary.ActMood;
import com.sunwayhorizo.health.hl7.vocabulary.ParticipationType;

/**
 * @ClassName ClinicLibraryManager <br>
 * @PackageName com.sunwayhorizo.health.business.clinic.emr.template <br>
 * @Description 诊疗库管理 <br>
 * @Author jinzw <br>
 * @Date 2011-04-08 <br>
 * @Version 1.0 <br>
 * @ModifiedDesc <br>
 * @ModifiedDate <br>
 * @ModifiedBy <br>
 * @Email jinzw@sunwaysoft.com.cn <br>
 * @Copyright 2010-2020 北京三维海容 All Rights Reserved. <br>
 */
@Name(value = "ClinicLibraryManager")
@Stateless
@SuppressWarnings("unused")
public class ClinicLibraryManager extends BaseManager implements ClinicLibraryManagerLocal
{
   private ClinicLibraryQueryLocal clinicLibraryQuery = (ClinicLibraryQueryLocal) Component.getInstance("ClinicLibraryQuery");
   private  DepartmentManagerLocal departManager = (DepartmentManagerLocal) Component.getInstance("DepartmentManager");
   private  TemplateQueryLocal templateQuery = (TemplateQueryLocal)Component.getInstance("TemplateQuery");

    public ResultsDTO newClinicLibrary(ClinicLibraryDTO clinicLibraryDTO) throws Hl7Exception
    {
        if (null == clinicLibraryDTO)
        {
            log.info("新增诊疗库失败，诊疗库数据clinicLibraryDTO为null");
            return getResultsDTO("新增诊疗库失败,诊断类别为空", false, null);
        }
        // 创建诊疗库动作
        Document doc = creatClincLibDoc();
        
        // 给doc进行赋值
        converDocToClinicLibDto(clinicLibraryDTO, doc);
        
        Role deptRole = null;
        if (null != clinicLibraryDTO.getBelongDept() && StrUtil.isNotEmpty(clinicLibraryDTO.getBelongDept().getRimDepartmentRoleId()))
        {
            // 科室RIM角色
            deptRole = baseQuery.findRoleById(Long.valueOf(clinicLibraryDTO.getBelongDept().getRimDepartmentRoleId()));
        }

        // 添加角色参与
        if (null != deptRole)
        {
            ActParticipation participation = getActFactory().newActParticipation();
            participation.setTypeCode(ParticipationType.SBJ);
            addParticipation(deptRole, participation);
        }

        ControlAct control = newControlAct(doc);
        
        em.persist(control);
        log.info("新增诊疗库成功docId " + doc.getActId());
        return getResultsDTO("新增诊疗库成功", true, doc.getActId().toString());
    }


    @SuppressWarnings("rawtypes")
    public ResultsDTO delClinicLibrary(List clinicLibIds) throws Hl7Exception
    {
        if (ListUtil.isEmpty(clinicLibIds))
        {
            log.info("删除诊疗库失败，clinicLibIds为空");
            return getResultsDTO("删除诊疗库失败,诊疗库主键为空", false, null);
        }

        String clinicLibId = (String) clinicLibIds.get(0);
        Document doc = baseQuery.findDocumentById(clinicLibId);
        em.remove(doc);

        log.info("删除诊疗库成功，id " + clinicLibId);
        return getResultsDTO("删除诊疗库成功", true, "");
    }


    @SuppressWarnings("null")
    public ResultsDTO updateClinicLibrary(ClinicLibraryDTO clinicLibraryDTO) throws Hl7Exception
    {
        if (null == clinicLibraryDTO || StrUtil.isEmpty(clinicLibraryDTO.getId()))
        {
            log.info("更新诊疗库失败，clinicLibraryDTO为空");
            return getResultsDTO("更新诊疗库失败，诊疗库信息为空", false, null);
        }
        
        String clinicLibId = clinicLibraryDTO.getId();

        //诊疗科动作
        Document doc = baseQuery.findDocumentById(clinicLibId); 
        //修改诊疗库信息
        converDocToClinicLibDto(clinicLibraryDTO, doc);
        // 修改科室信息
        modifyClinicLibPatcptnRole(clinicLibraryDTO,doc);
        
        em.merge(doc);
        log.info("更新诊疗库成功，id " + clinicLibId);
        return getResultsDTO("更新诊疗库成功", true, clinicLibId);
    }
    
    public ResultsDTO findClinicLibList(DictionaryDTO dictionaryDTO, DepartmentDTO departmentDTO) throws Hl7Exception
    {
        if ((null == dictionaryDTO))
        {
            log.info("获取诊疗库列表失败");
            return getResultsDTO("查询条件为空，没有对应的信息", false, null);
        }
        
        List<Object> docs = clinicLibraryQuery.findClinicLibList(dictionaryDTO.getConceptCode(), (departmentDTO != null ? departmentDTO.getRimDepartmentRoleId() : null));

        if (ListUtil.isEmpty(docs))
        {
            log.info("获取诊疗库列表失败，docs " + docs);
            return getResultsDTO("诊疗库列表内容为空", true, null);
        }
        List<ClinicLibraryDTO> result = converClinicLiDTOListByDocList(docs);

        log.info("获取诊疗库列表成功，共获取记录数： " + docs.size());
        return getResultsDTO("获取诊疗库列表成功 ", true, result);
    }


    public ResultsDTO findClinicLibList(DictionaryDTO dictionaryDTO, DepartmentDTO departmentDTO, int currentPage, int pageSize)
        throws Hl7Exception
    {
        if ((null == dictionaryDTO))
        {
            log.info("获取诊疗库列表失败，dictionaryDTO " + dictionaryDTO + "  departmentDTO" + departmentDTO);
            return getResultsDTO("查询条件为空，没有对应的信息", false, null);
        }
        List<Object> docs = clinicLibraryQuery.findClinicLibListByPage(dictionaryDTO.getConceptCode(), departmentDTO.getRimDepartmentRoleId(),
            currentPage, pageSize);

        List<ClinicLibraryDTO> result = converClinicLiDTOListByDocList(docs);

        log.info("获取诊疗库列表成功，共获取记录数： " + docs.size());
        return this.getResultsDTO("获取诊疗库列表成功", true, result);
    }


    public ResultsDTO findClinicLibrary(String clinicLibId) throws Hl7Exception
    {
        if (StrUtil.isEmpty(clinicLibId))
        {
            log.info("查询诊疗库失败，clinicLibId为空");
            return getResultsDTO("查询诊疗库失败，clinicLibId为空", true, null);
        }
        Document doc = baseQuery.findDocumentById(clinicLibId); 

        ClinicLibraryDTO result = convertDocToDto(doc);
        
        log.info("获取诊疗库成功 ");
        return getResultsDTO("获取诊疗库成功", true, result);
    }
    
    @SuppressWarnings("rawtypes")
    public ResultsDTO validateClinicLibName(String name) throws Hl7Exception
    {
        List list =clinicLibraryQuery.findActIdByName(name);
        if (ListUtil.isEmpty(list))
        {
            return this.getResultsDTO("验证通过", true, "1");
        }
        else
        {
            return this.getResultsDTO("验证通过", true, "0");
        }
    }

    private Document creatClincLibDoc() throws Hl7Exception
    {
        CS cs = ActMood.EVN;
        CE ce = getDataTypeFactory().newCE(ActCode.CLINIClIB.code().stringValue());
        Document document = this.getActFactory().newDocument(cs, ce, null);
        return document;
    }


    //将DTO中的相关信息设置到Document中
    private Document converDocToClinicLibDto(ClinicLibraryDTO clinicLib, Document document) throws Hl7Exception
    {
        if ((null == clinicLib) || (null == document))
            return null;

        // 设置诊疗库名称
        if (!StrUtil.isEmpty(clinicLib.getName()))
        {
            ST name = getDataTypeFactory().newST(clinicLib.getName());
            document.setTitle(name);
        }

        // 诊疗库内容
        String contents = clinicLib.getContents();
        if (StrUtil.isNotEmpty(contents))
        {
            // 如果内容不为空
            ED desc = DataTypeUtil.getED(clinicLib.getContents());
            document.setText(desc);
        }
        
        // 诊疗类别
        DictionaryDTO dicDto = clinicLib.getClinicClass();
        if (null != dicDto)
        {
            CE monitorCode = getDictionaryFactory().getCeByDictionaryDTO(dicDto);
            document.setCategoryCode(monitorCode);
        }

        // 创建人
        if (!StrUtil.isEmpty(clinicLib.getCreatedBy()))
        {
            document.setCreatedBy(Long.parseLong(clinicLib.getCreatedBy()));
            document.setCreationDate(DateUtil.getTimestamp(DateUtil.GetDateTime()));
        }

        // 最后修改人
        if (!StrUtil.isEmpty(clinicLib.getLastUpdateBy()))
        {
            document.setLastUpdatedBy(Long.parseLong(clinicLib.getLastUpdateBy()));
            document.setLastUpdateDate(DateUtil.getTimestamp(DateUtil.GetDateTime()));
        }

        return document;
    }


    //将Document转换为ClinicLibraryDTO
    private ClinicLibraryDTO convertDocToDto(Document doc) throws Hl7Exception
    {
        if (null == doc)  return null;
        ClinicLibraryDTO clDto = new ClinicLibraryDTO();
        // id
        clDto.setId(doc.getActId().toString());
        // 名称
        ST name = doc.getTitle();
        clDto.setName(name.stringValue());
        // 内容
        ED text = doc.getText();
        if (null != text)
            clDto.setContents(text.stringValue());
        // 诊疗类别
        if (ListUtil.isNotEmpty(doc.getActCdSetsList()))
        {
            CE ce = doc.getCategoryCode();
            clDto.setClinicClass(getDictionaryFactory().getDictionaryDTOByCe(ce));
        }
        List<ActParticipation> patcptns = doc.getParticipations();
        if (ListUtil.isNotEmpty(patcptns))
        {
            for (ActParticipation patcptn : patcptns)
            {
                if (patcptn.getTypecode().equals(ParticipationType.SBJ))
                {
                    // 诊疗科旧所属科室
                    RimCoreRoles role = patcptn.getRoleparticipation(); 
                    Role deptRole = baseQuery.findRoleById(role.getRoleId());
                    DepartmentDTO departmentDTO = departManager.convertDepartmentDTO((Organization)deptRole.getPlayerEntities());
                    clDto.setBelongDept(departmentDTO);
                }
            }
        }
        // 创建人
        clDto.setCreatedBy(doc.getCreatedBy().toString());
        // 创建时间
        clDto.setCreationDate(doc.getCreationDate());
        // 最后修改人
        clDto.setLastUpdateBy(doc.getLastUpdatedBy().toString());
        // 最后修改时间
        clDto.setLastUpdateDate(doc.getLastUpdateDate());
        return clDto;
    }
    
    // 修改参与到诊疗科的角色信息
    private void modifyClinicLibPatcptnRole(ClinicLibraryDTO clinicLibraryDTO,Document doc) throws Hl7Exception
    {
        if (null != clinicLibraryDTO.getBelongDept() && StrUtil.isNotEmpty(clinicLibraryDTO.getBelongDept().getRimDepartmentRoleId()))
        {
            List<ActParticipation> patcptns = doc.getParticipations();
            if (ListUtil.isNotEmpty(patcptns))
            {
                for (ActParticipation patcptn : patcptns)
                {
                    if (patcptn.getTypecode().equals(ParticipationType.SBJ))
                    {
                        // 诊疗科旧所属科室
                        Role role = (Role) patcptn.getRoleparticipation(); 
                        if (!clinicLibraryDTO.getBelongDept().getRimDepartmentRoleId().equals(String.valueOf(role.getRoleId())))
                        {
                            // 科室角色
                            Role deptRole = baseQuery.findRoleById(Long.valueOf(clinicLibraryDTO.getBelongDept().getRimDepartmentRoleId()));
                            patcptn.setRoleparticipation(deptRole);
                            em.merge(patcptn);
                            log.info("修改诊疗库科室成功");
                        }
                    }
                }
            }
            else
            {
                // 科室角色
                Role deptRole = baseQuery.findRoleById(Long.valueOf(clinicLibraryDTO.getBelongDept().getRimDepartmentRoleId()));
                doc.addPartWithOutEntRole(ParticipationType.SBJ, deptRole); // 诊疗库所属科室
            }
        }
    }
    
    private List<ClinicLibraryDTO> converClinicLiDTOListByDocList(List<Object> docs) throws Hl7Exception
    {
        if(ListUtil.isEmpty(docs)) return null;
        
        List<ClinicLibraryDTO> result = new ArrayList<ClinicLibraryDTO>();

        for (int i = 0; i < docs.size(); i++)
        {
            Object[] arg = (Object[]) docs.get(i);
            ClinicLibraryDTO cd = new ClinicLibraryDTO();
            if (null != arg[0])
            {
                cd.setId(arg[0].toString());
            }
            if (null != arg[1])
            {
                cd.setName(arg[1].toString());
            }
            result.add(cd);
        }
        return result;
    }
    
}
